package roles

import (
	"xagent/internal/actors"
	"xagent/internal/messages"
	proto "xagent/proto/v1"
)

// Engineer represents the software engineer role
type Engineer struct {
	*actors.BaseAgent
	currentTask *proto.Task
}

// NewEngineer creates a new engineer agent
func NewEngineer() *Engineer {
	baseAgent := actors.NewBaseAgent(
		"engineer",
		"Responsible for implementing system components and features",
	)
	return &Engineer{
		BaseAgent: baseAgent,
	}
}

// MessageAdapter adapts proto.AgentMessage to messages.Message
type MessageAdapter struct {
	*proto.AgentMessage
}

func (m *MessageAdapter) GetContent() string {
	if m.Content != nil {
		switch content := m.Content.(type) {
		case *proto.AgentMessage_Message:
			return content.Message
		case *proto.AgentMessage_Prediction:
			return content.Prediction.String()
		case *proto.AgentMessage_Error:
			return content.Error.Message
		}
	}
	return ""
}

func (m *MessageAdapter) GetRole() string {
	if meta := m.GetMetadata(); meta != nil {
		if role, ok := meta["role"]; ok {
			return role
		}
	}
	return "engineer"
}

func (m *MessageAdapter) GetType() messages.MessageType {
	switch m.Type {
	case proto.MessageType_MESSAGE_TYPE_RESPONSE:
		return messages.TypeResponse
	case proto.MessageType_MESSAGE_TYPE_REQUEST:
		return messages.TypeRequest
	case proto.MessageType_MESSAGE_TYPE_ERROR:
		return messages.TypeError
	default:
		return messages.TypeResponse
	}
}

func (m *MessageAdapter) GetAction() string {
	if meta := m.GetMetadata(); meta != nil {
		if action, ok := meta["type"]; ok {
			return action
		}
	}
	return ""
}

// ProcessTask handles engineering specific tasks
func (e *Engineer) processTask(msg interface{}) {
	switch t := msg.(type) {
	case *proto.Task:
		e.currentTask = t
		if t.Name == "ImplementCode" {
			e.implementCode(t)
		} else if t.Name == "WriteTests" {
			e.writeTests(t)
		} else if t.Name == "CodeReview" {
			e.reviewCode(t)
		}
	}
}

// implementCode handles code implementation tasks
func (e *Engineer) implementCode(task *proto.Task) {
	response := &proto.AgentMessage{
		Id:   task.Id,
		Type: proto.MessageType_MESSAGE_TYPE_RESPONSE,
		Content: &proto.AgentMessage_Message{
			Message: "Code implementation completed",
		},
		Metadata: map[string]string{
			"type":   "implementation",
			"status": "completed",
			"role":   "engineer",
		},
	}

	if parent := e.GetContext().Parent(); parent != nil {
		e.GetContext().Send(parent, response)
	}
}

// writeTests handles test writing tasks
func (e *Engineer) writeTests(task *proto.Task) {
	response := &proto.AgentMessage{
		Id:   task.Id,
		Type: proto.MessageType_MESSAGE_TYPE_RESPONSE,
		Content: &proto.AgentMessage_Message{
			Message: "Test cases written",
		},
		Metadata: map[string]string{
			"type":   "testing",
			"status": "completed",
			"role":   "engineer",
		},
	}

	if parent := e.GetContext().Parent(); parent != nil {
		e.GetContext().Send(parent, response)
	}
}

// reviewCode handles code review tasks
func (e *Engineer) reviewCode(task *proto.Task) {
	response := &proto.AgentMessage{
		Id:   task.Id,
		Type: proto.MessageType_MESSAGE_TYPE_RESPONSE,
		Content: &proto.AgentMessage_Message{
			Message: "Code review completed",
		},
		Metadata: map[string]string{
			"type":   "review",
			"status": "completed",
			"role":   "engineer",
		},
	}

	if parent := e.GetContext().Parent(); parent != nil {
		e.GetContext().Send(parent, response)
	}
}
